package service

import (
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/go-admin-team/go-admin-core/sdk/service"
	"gorm.io/gorm"
	"strconv"
	"strings"
	"time"
	"tuowei.com/app/admin/models"
	"tuowei.com/app/admin/service/dto"
	"tuowei.com/common/actions"
	cDto "tuowei.com/common/dto"
	"tuowei.com/pkg/xlog"
)

type SysOrder struct {
	service.Service
}

// GetOnlineOrderDetail 获取线下订单详情
func (e *SysOrder) GetOfflineOrderDetail(c *dto.SysOfflineOrderDetailRequest, p *actions.DataPermission, detail *models.OfflineOrder) error {
	var err error
	err = e.Orm.
		Preload("Customer.Recommenders").Preload("Customer.TeachRecommenders").
		Preload("Course.ESignContract", func(tx *gorm.DB) *gorm.DB {
			return e.Orm.Unscoped()
		}).Preload("Department.Department").Preload("SubjectRelation").
		Preload("Department.Province").
		Scopes(
			cDto.MakeCondition(*c),
			actions.Permission(detail.TableName(), p),
		).Table(detail.TableName()).
		First(detail).
		Error
	if err != nil {
		xlog.Error("db error: %s", err)
		return err
	}
	return nil
}

func (e *SysOrder) GetMaterialOrderDetail(c *dto.SysMaterialOrderDetailRequest, p *actions.DataPermission, detail *models.MaterialOrder) error {
	var err error
	err = e.Orm.Debug().
		Preload("Customer.Recommenders").Preload("Customer.TeachRecommenders").
		Preload("Material", func(tx *gorm.DB) *gorm.DB {
			return e.Orm.Unscoped()
		}).Preload("SubjectRelation").
		Scopes(
			cDto.MakeCondition(*c),
			actions.Permission(detail.TableName(), p),
		).Table(detail.TableName()).
		First(detail).
		Error
	if err != nil {
		xlog.Errorf("db error: %v", err)
		return err
	}
	return nil
}

// Insert 创建SysOrder对象
func (e *SysOrder) InsertMaterialOrder(c *dto.SysMaterialOrderAddRequest) (models.MaterialOrder, error) {
	var err error
	var data models.MaterialOrder

	c.Generate(&data)

	err = e.Orm.Create(&data).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return data, err
	}

	return data, nil
}

//GetOffLineOrderByStudentId 获取某个用户购买的线下课程的所有课程id
func (e *SysOrder) GetOffLineOrderByStudentId(studentId int) []int {
	var arr []int
	e.Orm.Model(models.OfflineOrder{}).Distinct(
		"offline_order_course.course_id").
		Joins("INNER JOIN offline_order_course ON offline_order_course.order_id = sys_offline_order.id").
		Where("buyer_id = ?", studentId).Pluck("course_id", &arr)
	return arr
}

func (e *SysOrder) InsertLinkOrder(c *dto.SysLinkOrderAddRequest) (models.LinkOrder, error) {
	var err error
	var data models.LinkOrder

	c.Generate(&data)

	err = e.Orm.Create(&data).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return data, err
	}

	return data, nil
}

// Insert 创建SysOrder对象
func (e *SysOrder) InsertOfflineOrder(c *dto.SysOfflineOrderAddRequest) (models.OfflineOrder, error) {
	var err error
	var data models.OfflineOrder
	c.Generate(&data)
	//根据就读院校查找教学点
	TeachingPointId := 0
	err = e.Orm.Table("sys_colleges").Select("teaching_point_id").Where("id=?", c.CollegeId).Scan(&TeachingPointId).Error
	if err != nil {
		xlog.Errorf("db error: %s", err)
	}
	if TeachingPointId == 0 {
		return data, errors.New("就读院校未绑定教学点")
	}
	//更新学生个人信息
	err = e.Orm.Table("sys_student").Where("id=?", c.BuyerId).
		Updates(map[string]interface{}{"name": c.Name, "college_id": c.CollegeId,
			"grade": c.Grade, "ke_bie": c.KeBie, "area": TeachingPointId}).Error
	if err != nil {
		xlog.Errorf("db error: %s", err)
		return data, err
	}
	//查找教学点
	//area := 0
	//err = e.Orm.Table("sys_student").Select("area").Where("id=?", c.BuyerId).Scan(&area).Error
	//if err != nil {
	//	xlog.Errorf("db error: %s", err)
	//}
	//if area == 0 {
	//	return data, errors.New("未找到教学点")
	//}
	data.TeachingPointId = TeachingPointId
	data.DeptId = TeachingPointId
	//待分配
	data.Status = 1
	postId := 0
	//他的上级是一个招生老师
	teachRecommender := 0
	err = e.Orm.Table("sys_student").Select("teach_recommender").Where("id=?", c.BuyerId).Scan(&teachRecommender).Error
	if err != nil {
		xlog.Errorf("db error: %s", err)
	}
	if teachRecommender != 0 {
		err = e.Orm.Table("sys_user").Select("post_id").Where("user_id=?", teachRecommender).Scan(&postId).Error
		if err != nil {
			xlog.Errorf("db error: %s", err)
		}
		if postId == 49 || postId == 50 || postId == 51 || postId == 52 {
			//上级是老师且为招生老师
			data.Status = 2
			data.EnrollmentTeacherId = teachRecommender
		}

	}
	//线下课程暂时没得积分
	err = e.Orm.Create(&data).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return data, err
	}
	// 添加月份

	if postId == 49 || postId == 50 || postId == 51 || postId == 52 {
		//上级是老师且为招生老师
		offlineOrderProgress := models.OfflineOrderProgress{}
		offlineOrderProgress.Status = 2
		offlineOrderProgress.Creator = "报名上级为招生老师"
		offlineOrderProgress.OrderId = data.Id
		offlineOrderProgress.OperateTime = time.Now().Local()
		err = e.Orm.Create(&offlineOrderProgress).Error
		if err != nil {
			e.Log.Errorf("db error: %s", err)
			return data, err
		}
	}
	return data, nil
}
func (e *SysOrder) InsertOnlineOrder(c *dto.SysOnlineOrderAddRequest) (models.OnlineOrder, error) {
	var err error
	var data models.OnlineOrder

	c.Generate(&data)

	err = e.Orm.Create(&data).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return data, err
	}

	return data, nil
}

// GetOnlineOrderDetail 获取在线订单详情
func (e *SysOrder) GetOnlineOrderDetail(c *dto.SysOnlineOrderDetailRequest, p *actions.DataPermission, detail *models.OnlineOrder) error {
	var err error
	err = e.Orm.
		Preload("Customer.Recommenders").Preload("Customer.TeachRecommenders").
		Preload("Teacher").Preload("Course", func(tx *gorm.DB) *gorm.DB {
		return e.Orm.Unscoped()
	}).Preload("SubjectRelation").
		Scopes(
			cDto.MakeCondition(*c),
			actions.Permission(detail.TableName(), p),
		).Table(detail.TableName()).
		First(detail).
		Error
	if err != nil {
		xlog.Error("db error: %s", err)
		return err
	}
	if detail.SubjectRelation != nil {
		detail.Subject = detail.SubjectRelation.Name
	}
	return nil
}

// GetOfflineOrderList 获取线下订单列表
func (e *SysOrder) GetOfflineOrderList(c *dto.SysOfflineOrderListRequest, p *actions.DataPermission, list *[]models.OfflineOrder, count *int64, totalMoney *float64) error {
	var err error
	// 如果有课程名字
	courseIds := make([]int, 0)
	orderIds := make([]int, 0)
	if c.CourseName != "" {
		e.Orm.Model(models.SysOfflineCourse{}).Where("name like ?", "%"+c.CourseName+"%").Pluck("course_id", &courseIds)
		if len(courseIds) == 0 {
			return nil
		} else {
			e.Orm.Model(models.OfflineOrderCourse{}).Where("course_id in (?)", courseIds).Pluck("order_id", &orderIds)
			if len(orderIds) == 0 {
				return nil
			}
		}
	}
	var data models.OfflineOrder
	db := e.Orm.
		Preload("Customer.Recommenders").Preload("Customer.TeachRecommenders").
		Preload("Course").
		Preload("Department.Department").
		Preload("SubjectRelation").
		Preload("RecheckUser").
		Scopes(
			cDto.MakeCondition(*c),
			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
			actions.Permission(data.TableName(), p),
		).Table(data.TableName())
	if c.Phone != "" {
		db.Joins("inner join sys_student as stu on stu.id = sys_offline_order.buyer_id").Where("stu.phone = ?", c.Phone)
	}
	if len(orderIds) > 0 {
		db.Where("id in (?)", orderIds)
	}
	err = db.Order("id desc").
		Find(list).Limit(-1).Offset(-1).
		Count(count).Error
	if err != nil {
		xlog.Error("db error: %v", err)
		return err
	}
	// 获取总金额
	var sum []float64
	e.Orm.Scopes(
		cDto.MakeCondition(*c),
		actions.Permission(data.TableName(), p),
	).Table(data.TableName()).Pluck("sum(price) as totalMoney", &sum).Row()
	*totalMoney = sum[0]

	return nil
}

// GetMaterialOrderList 获取资料订单列表
func (e *SysOrder) GetMaterialOrderList(c *dto.SysMaterialOrderListRequest, p *actions.DataPermission, list *[]models.MaterialOrder, count *int64, totalMoney *float64) error {
	var err error
	var data models.MaterialOrder
	db := e.Orm.
		Preload("Customer.Recommenders").Preload("Customer.TeachRecommenders").
		Preload("Material", func(tx *gorm.DB) *gorm.DB {
			return e.Orm.Unscoped()
		}).Preload("SubjectRelation").Preload("DeliverUser").
		Scopes(
			cDto.MakeCondition(*c),
			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
			actions.Permission(data.TableName(), p),
		).Table(data.TableName()).Order("id desc")
	if c.Phone != "" {
		db.Joins("inner join sys_student as stu on stu.id = sys_material_order.buyer_id").Where("stu.phone = ?", c.Phone)
	}
	err = db.Find(list).Limit(-1).Offset(-1).Count(count).Error
	if err != nil {
		xlog.Warn("db error: %v", err)
		return err
	}
	// 获取总金额
	var sum []float64
	e.Orm.Scopes(
		cDto.MakeCondition(*c),
		actions.Permission(data.TableName(), p),
	).Table(data.TableName()).Pluck("sum(price) as totalMoney", &sum).Row()
	*totalMoney = sum[0]

	return nil
}

// GetMaterialOrderList 获取资料订单列表
func (e *SysOrder) GetMaterialOrderListId(id int, c *dto.SysMaterialOrderListRequest, p *actions.DataPermission, list *[]models.MaterialOrder, count *int64, totalMoney *float64) error {
	var err error
	var data models.MaterialOrder
	err = e.Orm.
		Preload("Customer.Recommenders").Preload("Customer.TeachRecommenders").
		Preload("Material", func(tx *gorm.DB) *gorm.DB {
			return e.Orm.Unscoped()
		}).
		Preload("SubjectRelation").
		Scopes(
			cDto.MakeCondition(*c),
			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
			actions.Permission(data.TableName(), p),
		).Table(data.TableName()).Where("id > ?", id).Order("id desc").
		Find(list).Limit(-1).Offset(-1).
		Count(count).Error
	// 获取总金额
	var sum []float64
	e.Orm.Scopes(
		cDto.MakeCondition(*c),
		actions.Permission(data.TableName(), p),
	).Table(data.TableName()).Pluck("sum(price) as totalMoney", &sum).Row()
	*totalMoney = sum[0]
	if err != nil {
		xlog.Error("db error: %v", err)
		return err
	}
	return nil
}

func (e *SysOrder) GetLinkOrderList(c *dto.SysLinkOrderListRequest, p *actions.DataPermission, list *[]models.LinkOrder, count *int64) error {
	var err error
	var data models.LinkOrder

	err = e.Orm.
		Scopes(
			cDto.MakeCondition(c.GetNeedSearch()),
			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
			actions.Permission(data.TableName(), p),
		).Table(data.TableName()).Order("id desc").
		Find(list).Limit(-1).Offset(-1).
		Count(count).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return err
	}
	return nil
}

// GetOnlineOrderList 获取在线订单列表
func (e *SysOrder) GetOnlineOrderList(c *dto.SysOnlineOrderListRequest, p *actions.DataPermission, list *[]models.OnlineOrder, count *int64, totalMoney *float64) error {
	var err error
	var data models.OnlineOrder
	db := e.Orm.Preload("Customer.Recommenders").Preload("Customer.TeachRecommenders").
		Preload("Course", func(tx *gorm.DB) *gorm.DB {
			return tx.Unscoped()
		}).
		Preload("Teacher").Preload("SubjectRelation").
		Scopes(
			cDto.MakeCondition(c.GetNeedSearch()),
			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
			actions.Permission(data.TableName(), p),
		).Table(data.TableName())
	if c.Phone != "" {
		db.Joins("inner join sys_student as stu on stu.id = sys_online_order.buyer_id").Where("stu.phone = ?", c.Phone)
	}
	err = db.Order("id desc").Find(list).Limit(-1).Offset(-1).Count(count).Error
	// 获取总金额
	var sum []float64
	e.Orm.Scopes(
		cDto.MakeCondition(c.GetNeedSearch()),
		actions.Permission(data.TableName(), p),
	).Table(data.TableName()).Pluck("sum(price) as totalMoney", &sum).Row()
	*totalMoney = sum[0]
	// 获取总金额
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return err
	}
	return nil
}

func (e *SysOrder) UpdateByModel(model *models.MaterialOrder, p *actions.DataPermission) error {
	db := e.Orm.
		Scopes(actions.Permission(model.TableName(), p)).
		Save(model)
	if db.Error != nil {
		return db.Error
	}
	if db.RowsAffected == 0 {
		return errors.New("更新影响行数为0")
	}
	return nil
}
func (e *SysOrder) UpdateOnlineByModel(model *models.OnlineOrder, p *actions.DataPermission) error {
	db := e.Orm.
		Scopes(actions.Permission(model.TableName(), p)).
		Save(model)
	if db.Error != nil {
		return db.Error
	}
	if db.RowsAffected == 0 {
		return errors.New("更新影响行数为0")
	}
	return nil
}
func (e *SysOrder) UpdateMaterialByModel(model *models.MaterialOrder, p *actions.DataPermission) error {
	db := e.Orm.
		Scopes(actions.Permission(model.TableName(), p)).
		Save(model)
	if db.Error != nil {
		return db.Error
	}
	if db.RowsAffected == 0 {
		return errors.New("更新影响行数为0")
	}
	return nil
}

func (e *SysOrder) Update(c *dto.SysOfflineOrderRecheckUpdateRequest, ctx *gin.Context) error {
	var err error
	model := models.OfflineOrder{}
	model.Id = c.Id
	err = e.Orm.Preload("Course", func(tx *gorm.DB) *gorm.DB {
		return e.Orm.Unscoped()
	}).First(&model).Error
	c.Generate(&model)
	db := e.Orm.Save(&model)
	err = db.Error
	if err != nil {
		e.Log.Errorf("Service Update SysOfflineOrderRecheckUpdateRequest error:%s", err)
		return err
	}
	if db.RowsAffected == 0 {
		return errors.New("无权更新该数据")

	}
	//复审通过之后，检查改学生是否分班
	if c.RecheckOk == 1 {
		err := e.Orm.Table("sys_link_order").Where("order_number=?", model.OrderNumber).Update("status", 5).Error
		if err != nil {
			xlog.Errorf("db error: %s", err)
			return err
		}
		var dataStu models.SysStudent
		err = e.Orm.Debug().Table(dataStu.TableName()).Where("id = ?", model.BuyerId).First(&dataStu).Error
		if err != nil {
			e.Log.Errorf("SysStudent  First error: %s", err)
		}
		err = e.Orm.Table("sys_student").Where("id=?", dataStu.Id).Update("user_type", "线下").Error
		if err != nil {
			xlog.Errorf("db error: %s", err)
			return err
		}
		if dataStu.ClassId == 0 {
			err = e.Orm.Table(dataStu.TableName()).Where("id = ?", dataStu.Id).Update("progress_status", 3).Error
			if err != nil {
				e.Log.Errorf("SysStudent  Update error: %s", err)
			}
		}
		//查询该订单的线下课程
		modeloc := models.OfflineOrderCourse{}
		err = e.Orm.Table(modeloc.TableName()).Where("order_id = ?", model.Id).First(&modeloc).Error
		if err != nil {
			e.Log.Errorf("OfflineOrderCourse  First error: %s", err)
			return err
		}
		modelc := models.SysOfflineCourse{}
		err = e.Orm.Table(modelc.TableName()).Where("course_id = ?", modeloc.CourseId).Scan(&modelc).Error
		if err != nil {
			e.Log.Errorf("SysOfflineCourse  First error: %s", err)
			return err
		}
		xlog.Infof("SysOfflineCourse:%+v", modelc)
		////添加该面授课程关联的线上课程到学习页面
		if modelc.BindingOnlineId != "" {
			OnlineId := strings.Split(modelc.BindingOnlineId, ",")
			xlog.Info("OnlineId:", OnlineId)
			for _, onlineId := range OnlineId {
				if onlineId == "" {
					xlog.Info("OnlineIdOnlineId")
					continue
				}
				id, err := strconv.Atoi(onlineId)
				if err != nil {
					xlog.Info("OnlineIdOnlineId:err", err)
					continue
				}
				var data models.SysCourse
				err = e.Orm.Table(data.TableName()).Where("course_id = ?", id).
					First(&data).Error
				if err != nil {
					xlog.Errorf("db error: %s", err)
					continue
				}
				//onlineClassId = data.OnlineClassId
				//添加learning-list
				type Learningl struct {
					CourseId int    `json:"course_id" gorm:"int(10);comment:课程ID"`
					Name     string `json:"name" gorm:"varchar(20);comment:学习名称"`
					Cover    string `json:"cover" gorm:"varchar(255);comment:学习封面"`
					Status   int    `json:"status" gorm:"tinyint(2);comment:学习状态"`
					BuyerId  int    `json:"buyer_id" comment:"购买学员ID"`
					Subject  string `json:"subject" comment:"科目"`
				}
				d := Learningl{}
				d.BuyerId = model.BuyerId
				d.CourseId = id
				d.Name = data.Name
				d.Cover = data.Cover
				d.Subject = data.Subject
				d.Status = -1
				dl := &Learningl{}
				err = e.Orm.Table("sys_learning_list").Where("buyer_id = ? and course_id = ?", d.BuyerId, d.CourseId).First(dl).Error
				if err != nil && err != gorm.ErrRecordNotFound {
					xlog.Errorf("db error: %s", err)
					continue
				}
				if dl.CourseId == 0 || (dl.CourseId != 0 && dl.Status == 2) {
					err = e.Orm.Table("sys_learning_list").Create(&d).Error
					if err != nil {
						xlog.Errorf("db error: %s", err)
						continue
					}
				}

			}
		}
		//等级
		switch dataStu.UserLabel {
		case "VIP":
			if modelc.ClassType == "普通" {
				modelc.ClassType = "VIP"
			}
		case "SVIP":
			modelc.ClassType = "SVIP"
		}
		totalPay := float64(dataStu.TotalPay) + model.ActualIncome
		//复审之后，更新学员信息，学员标识，学员等级，食宿说明,集训天数
		err = e.Orm.Table(dataStu.TableName()).Where("id = ?", dataStu.Id).Updates(map[string]interface{}{"user_label": modelc.ClassType,
			"explain": modelc.Explain, "training_days": modelc.TrainingDays, "total_pay": totalPay}).Error
		if err != nil {
			e.Log.Errorf("SysStudent  Update error: %s", err)
			return err
		}
		//返佣
		//买家id查询上级是否为学生，等级
		//邀请直接购买
		if dataStu.Recommender == 0 {
			xlog.Info("学生没有上级dataStu :", dataStu.Name)
			return nil
		}
		userLabel := ""
		err = e.Orm.Table("sys_student").Select("user_label").Where("id=?", dataStu.Recommender).Scan(&userLabel).Error
		if err != nil {
			xlog.Errorf("db error: %s", err)
			return nil

		}
		s := models.SysConfigCommission{}
		err = e.Orm.Table(s.TableName()).First(&s).Error
		if err != nil {
			xlog.Errorf("db error: %s", err)
			return nil
		}
		//返佣比例
		commissionPercentage := 0.00
		//推荐人用户类型，普通，vip，svip
		switch userLabel {
		case "普通":
			commissionPercentage = s.UserCommissionPer
		case "VIP":
			commissionPercentage = s.VipCommissionPercentage
		case "SVIP":
			commissionPercentage = s.SVipCommissionPercentage
		default:
			xlog.Errorf("db userLabel: %s;dataStu.Recommender:%d", userLabel, dataStu.Recommender)
			return nil
		}
		//佣金计算
		com := model.ActualIncome * commissionPercentage
		b := dataStu.Balance + float32(com)
		//分佣加余额
		err = e.Orm.Table("sys_student").Where("id=?", dataStu.Recommender).Update("balance", b).Error
		if err != nil {
			xlog.Errorf("db error: %s", err)
			return nil
		}
		//余额明细
		type SysBalanceDetail struct {
			BuyerId       int       `comment:"买家id" json:"buyer_id"` //买家id
			Title         string    `gorm:"type:varchar(64);not null;default:'';comment:余额变动标题" json:"title"`
			BalanceChange float64   `gorm:"type:decimal(10,2);comment:余额变动" json:"balance_change"`
			Change        int       `gorm:"type:int(10);not null;default:1;index;comment:1余额收入或者支出" json:"change"`
			BalanceSum    float64   `gorm:"type:decimal(10,2);comment:本次变动后的余额总额" json:"balance_sum"`
			CreatedAt     time.Time `json:"createdAt" gorm:"comment:创建时间"`
		}
		data := SysBalanceDetail{}
		data.BuyerId = dataStu.Recommender
		data.BalanceChange = com
		data.Change = 1
		data.Title = "邀请人消费返佣"
		data.CreatedAt = time.Now().Local()
		err = e.Orm.Table("sys_balance_detail").Create(&data).Error
		if err != nil {
			e.Log.Errorf("db error: %s", err)
			return nil
		}
		//更新订单佣金
		err = e.Orm.Table("sys_offline_order").Where("order_number=?", model.OrderNumber).Update("commission", com).Error
		if err != nil {
			xlog.Errorf("db error: %s", err)
			return nil
		}
	}
	return nil
}

// GetListsByOrderId 根据订单id查询当前订单的操作记录

func (e *SysOrder) GetListsByOrderId(lists *[]models.OfflineOrderProgress, orderId int) error {
	db := e.Orm.
		// 待分配那异步不要了
		Where("order_id = ?", orderId).Where("status != 2").Order("status asc").Find(lists)
	if db.Error != nil {
		return db.Error
	}
	return nil
}

// GetBill 获取系统账单
func (e *SysOrder) GetBill() (int64, int64, int64, int64, int64, error) {
	var err error
	var dataStu models.SysStudent
	var countStu int64
	err = e.Orm.Debug().Table(dataStu.TableName()).Where("deleted_at is null").Count(&countStu).Error
	if err != nil {
		e.Log.Errorf("SysStudent  Count error: %s", err)
		return 0, 0, 0, 0, 0, err
	}
	var dataLec models.SysLecturer
	var countLec int64
	err = e.Orm.Debug().Table(dataLec.TableName()).Where("deleted_at is null").Count(&countLec).Error
	if err != nil {
		e.Log.Errorf("db SysLecturer Count error: %s", err)
		return 0, 0, 0, 0, 0, err
	}
	var dataOnl models.OnlineOrder
	var countOnl int64
	err = e.Orm.Debug().Table(dataOnl.TableName()).Where("deleted_at is null").Count(&countOnl).Error
	if err != nil {
		e.Log.Errorf("db OnlineOrder Count error: %s", err)
		return 0, 0, 0, 0, 0, err
	}
	var dataOff models.OfflineOrder
	var countOff int64

	err = e.Orm.Debug().Table(dataOff.TableName()).Where("deleted_at is null").Count(&countOff).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return 0, 0, 0, 0, 0, err
	}
	var dataMat models.MaterialOrder
	var countMat int64

	err = e.Orm.Debug().Table(dataMat.TableName()).Where("deleted_at is null").Count(&countMat).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return 0, 0, 0, 0, 0, err
	}
	return countStu, countLec, countOnl, countOff, countMat, nil
}
func (e *SysOrder) GetBillTodayAndYesterday(count string) (int64, int64, interface{}, interface{}, error) {
	today := time.Now().Local().Format("2006-01-02")
	yesterday := time.Now().Local().AddDate(0, 0, -1).Format("2006-01-02")
	tomorrow := time.Now().Local().AddDate(0, 0, 1).Format("2006-01-02")

	switch count {
	case "countOnl":
		var dataOnl models.OnlineOrder
		var countOnltoday int64
		err := e.Orm.Debug().Table(dataOnl.TableName()).Where("deleted_at is null and created_at like ?", "%"+today+"%").Count(&countOnltoday).Error
		if err != nil {
			e.Log.Errorf("db OnlineOrder Count error: %s", err)
			return 0, 0, nil, nil, err
		}
		var countOnlyesterday int64
		err = e.Orm.Debug().Table(dataOnl.TableName()).Where("deleted_at is null and created_at like ?", "%"+yesterday+"%").Count(&countOnlyesterday).Error
		if err != nil {
			e.Log.Errorf("db OnlineOrder Count error: %s", err)
			return 0, 0, nil, nil, err
		}
		HourCountList := make([]HourCount, 0)
		err = e.Orm.Debug().Raw("SELECT HOUR ( m.created_at ) AS hour,count( * ) AS count FROM sys_online_order m WHERE m.deleted_at is null and m.created_at between ? and ? GROUP BY HOUR ( m.created_at ) ORDER BY HOUR ( m.created_at )", today, tomorrow).Scan(&HourCountList).Error
		if err != nil {
			e.Log.Errorf("db OnlineOrder Count error: %s", err)
			return 0, 0, nil, nil, err
		}
		HourCountListYesterday := make([]HourCount, 0)
		err = e.Orm.Debug().Raw("SELECT HOUR ( m.created_at ) AS hour,count( * ) AS count FROM sys_online_order m WHERE m.deleted_at is null and m.created_at between ? and ? GROUP BY HOUR ( m.created_at ) ORDER BY HOUR ( m.created_at )", yesterday, today).Scan(&HourCountListYesterday).Error
		if err != nil {
			e.Log.Errorf("db OnlineOrder Count error: %s", err)
			return 0, 0, nil, nil, err
		}
		hcl := []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
		hcly := []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
		if len(HourCountList) > 0 {
			for _, v := range HourCountList {
				if v.Hour == 0 || v.Hour == 1 {
					hcl[0] = hcl[0] + v.Count
				}
				if v.Hour == 2 || v.Hour == 3 {
					hcl[1] = hcl[1] + v.Count
				}
				if v.Hour == 4 || v.Hour == 5 {
					hcl[2] = hcl[2] + v.Count
				}
				if v.Hour == 6 || v.Hour == 7 {
					hcl[3] = hcl[3] + v.Count
				}
				if v.Hour == 8 || v.Hour == 9 {
					hcl[4] = hcl[4] + v.Count
				}
				if v.Hour == 10 || v.Hour == 11 {
					hcl[5] = hcl[5] + v.Count
				}
				if v.Hour == 12 || v.Hour == 13 {
					hcl[6] = hcl[6] + v.Count
				}
				if v.Hour == 14 || v.Hour == 15 {
					hcl[7] = hcl[7] + v.Count
				}
				if v.Hour == 16 || v.Hour == 17 {
					hcl[8] = hcl[8] + v.Count
				}
				if v.Hour == 18 || v.Hour == 19 {
					hcl[9] = hcl[9] + v.Count
				}
				if v.Hour == 20 || v.Hour == 21 {
					hcl[10] = hcl[10] + v.Count
				}
				if v.Hour == 22 || v.Hour == 23 {
					hcl[11] = hcl[11] + v.Count
				}
			}
		} else {
			hcl = []int{}
			if len(HourCountListYesterday) > 0 {
				for _, v := range HourCountListYesterday {
					if v.Hour == 0 || v.Hour == 1 {
						hcly[0] = hcly[0] + v.Count
					}
					if v.Hour == 2 || v.Hour == 3 {
						hcly[1] = hcly[1] + v.Count
					}
					if v.Hour == 4 || v.Hour == 5 {
						hcly[2] = hcly[2] + v.Count
					}
					if v.Hour == 6 || v.Hour == 7 {
						hcly[3] = hcly[3] + v.Count
					}
					if v.Hour == 8 || v.Hour == 9 {
						hcly[4] = hcly[4] + v.Count
					}
					if v.Hour == 10 || v.Hour == 11 {
						hcly[5] = hcly[5] + v.Count
					}
					if v.Hour == 12 || v.Hour == 13 {
						hcly[6] = hcly[6] + v.Count
					}
					if v.Hour == 14 || v.Hour == 15 {
						hcly[7] = hcly[7] + v.Count
					}
					if v.Hour == 16 || v.Hour == 17 {
						hcly[8] = hcly[8] + v.Count
					}
					if v.Hour == 18 || v.Hour == 19 {
						hcly[9] = hcly[9] + v.Count
					}
					if v.Hour == 20 || v.Hour == 21 {
						hcly[10] = hcly[10] + v.Count
					}
					if v.Hour == 22 || v.Hour == 23 {
						hcly[11] = hcly[11] + v.Count
					}
				}
			} else {
				hcly = []int{}
			}
		}
		return countOnltoday, countOnlyesterday, hcly, hcl, err
	case "countOff":
		var dataOff models.OfflineOrder
		var countOfftoday int64
		err := e.Orm.Debug().Table(dataOff.TableName()).Where("deleted_at is null and created_at like ?", "%"+today+"%").Count(&countOfftoday).Error
		if err != nil {
			e.Log.Errorf("db OnlineOrder Count error: %s", err)
			return 0, 0, nil, nil, err
		}
		var countOffyesterday int64
		err = e.Orm.Debug().Table(dataOff.TableName()).Where("deleted_at is null and created_at like ?", "%"+yesterday+"%").Count(&countOffyesterday).Error
		if err != nil {
			e.Log.Errorf("db OnlineOrder Count error: %s", err)
			return 0, 0, nil, nil, err
		}
		HourCountList := make([]HourCount, 0)
		err = e.Orm.Debug().Raw("SELECT HOUR ( m.created_at ) AS hour,count( * ) AS count FROM sys_offline_order m WHERE m.deleted_at is null and m.created_at between ? and ? GROUP BY HOUR ( m.created_at ) ORDER BY HOUR ( m.created_at )", today, tomorrow).Scan(&HourCountList).Error
		if err != nil {
			e.Log.Errorf("db OnlineOrder Count error: %s", err)
			return 0, 0, nil, nil, err
		}
		HourCountListYesterday := make([]HourCount, 0)
		err = e.Orm.Debug().Raw("SELECT HOUR ( m.created_at ) AS hour,count( * ) AS count FROM sys_offline_order m WHERE m.deleted_at is null and m.created_at between ? and ? GROUP BY HOUR ( m.created_at ) ORDER BY HOUR ( m.created_at )", yesterday, today).Scan(&HourCountListYesterday).Error
		if err != nil {
			e.Log.Errorf("db OnlineOrder Count error: %s", err)
			return 0, 0, nil, nil, err
		}
		hcl := []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
		hcly := []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
		if len(HourCountList) > 0 {
			for _, v := range HourCountList {
				if v.Hour == 0 || v.Hour == 1 {
					hcl[0] = hcl[0] + v.Count
				}
				if v.Hour == 2 || v.Hour == 3 {
					hcl[1] = hcl[1] + v.Count
				}
				if v.Hour == 4 || v.Hour == 5 {
					hcl[2] = hcl[2] + v.Count
				}
				if v.Hour == 6 || v.Hour == 7 {
					hcl[3] = hcl[3] + v.Count
				}
				if v.Hour == 8 || v.Hour == 9 {
					hcl[4] = hcl[4] + v.Count
				}
				if v.Hour == 10 || v.Hour == 11 {
					hcl[5] = hcl[5] + v.Count
				}
				if v.Hour == 12 || v.Hour == 13 {
					hcl[6] = hcl[6] + v.Count
				}
				if v.Hour == 14 || v.Hour == 15 {
					hcl[7] = hcl[7] + v.Count
				}
				if v.Hour == 16 || v.Hour == 17 {
					hcl[8] = hcl[8] + v.Count
				}
				if v.Hour == 18 || v.Hour == 19 {
					hcl[9] = hcl[9] + v.Count
				}
				if v.Hour == 20 || v.Hour == 21 {
					hcl[10] = hcl[10] + v.Count
				}
				if v.Hour == 22 || v.Hour == 23 {
					hcl[11] = hcl[11] + v.Count
				}
			}
		} else {
			hcl = []int{}
		}
		if len(HourCountListYesterday) > 0 {
			for _, v := range HourCountListYesterday {
				if v.Hour == 0 || v.Hour == 1 {
					hcly[0] = hcly[0] + v.Count
				}
				if v.Hour == 2 || v.Hour == 3 {
					hcly[1] = hcly[1] + v.Count
				}
				if v.Hour == 4 || v.Hour == 5 {
					hcly[2] = hcly[2] + v.Count
				}
				if v.Hour == 6 || v.Hour == 7 {
					hcly[3] = hcly[3] + v.Count
				}
				if v.Hour == 8 || v.Hour == 9 {
					hcly[4] = hcly[4] + v.Count
				}
				if v.Hour == 10 || v.Hour == 11 {
					hcly[5] = hcly[5] + v.Count
				}
				if v.Hour == 12 || v.Hour == 13 {
					hcly[6] = hcly[6] + v.Count
				}
				if v.Hour == 14 || v.Hour == 15 {
					hcly[7] = hcly[7] + v.Count
				}
				if v.Hour == 16 || v.Hour == 17 {
					hcly[8] = hcly[8] + v.Count
				}
				if v.Hour == 18 || v.Hour == 19 {
					hcly[9] = hcly[9] + v.Count
				}
				if v.Hour == 20 || v.Hour == 21 {
					hcly[10] = hcly[10] + v.Count
				}
				if v.Hour == 22 || v.Hour == 23 {
					hcly[11] = hcly[11] + v.Count
				}
			}
		} else {
			hcly = []int{}
		}
		return countOfftoday, countOffyesterday, hcly, hcl, err
	case "countMat":
		var dataMat models.MaterialOrder
		var countMattoday int64
		err := e.Orm.Debug().Table(dataMat.TableName()).Where("deleted_at is null and created_at like ?", "%"+today+"%").Count(&countMattoday).Error
		if err != nil {
			e.Log.Errorf("db OnlineOrder Count error: %s", err)
			return 0, 0, nil, nil, err
		}
		var countMatyesterday int64
		err = e.Orm.Debug().Table(dataMat.TableName()).Where("deleted_at is null and created_at like ?", "%"+yesterday+"%").Count(&countMatyesterday).Error
		if err != nil {
			e.Log.Errorf("db OnlineOrder Count error: %s", err)
			return 0, 0, nil, nil, err
		}

		HourCountList := make([]HourCount, 0)
		err = e.Orm.Debug().Raw("SELECT HOUR ( m.created_at ) AS hour,count( * ) AS count FROM sys_material_order m WHERE m.deleted_at is null and m.created_at between ? and ? GROUP BY HOUR ( m.created_at ) ORDER BY HOUR ( m.created_at )", today, tomorrow).Scan(&HourCountList).Error
		if err != nil {
			e.Log.Errorf("db OnlineOrder Count error: %s", err)
			return 0, 0, nil, nil, err
		}
		HourCountListYesterday := make([]HourCount, 0)
		err = e.Orm.Debug().Raw("SELECT HOUR ( m.created_at ) AS hour,count( * ) AS count FROM sys_material_order m WHERE m.deleted_at is null and m.created_at between ? and ? GROUP BY HOUR ( m.created_at ) ORDER BY HOUR ( m.created_at )", yesterday, today).Scan(&HourCountListYesterday).Error
		if err != nil {
			e.Log.Errorf("db OnlineOrder Count error: %s", err)
			return 0, 0, nil, nil, err
		}
		hcl := []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
		hcly := []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
		if len(HourCountList) > 0 {
			for _, v := range HourCountList {
				if v.Hour == 0 || v.Hour == 1 {
					hcl[0] = hcl[0] + v.Count
				}
				if v.Hour == 2 || v.Hour == 3 {
					hcl[1] = hcl[1] + v.Count
				}
				if v.Hour == 4 || v.Hour == 5 {
					hcl[2] = hcl[2] + v.Count
				}
				if v.Hour == 6 || v.Hour == 7 {
					hcl[3] = hcl[3] + v.Count
				}
				if v.Hour == 8 || v.Hour == 9 {
					hcl[4] = hcl[4] + v.Count
				}
				if v.Hour == 10 || v.Hour == 11 {
					hcl[5] = hcl[5] + v.Count
				}
				if v.Hour == 12 || v.Hour == 13 {
					hcl[6] = hcl[6] + v.Count
				}
				if v.Hour == 14 || v.Hour == 15 {
					hcl[7] = hcl[7] + v.Count
				}
				if v.Hour == 16 || v.Hour == 17 {
					hcl[8] = hcl[8] + v.Count
				}
				if v.Hour == 18 || v.Hour == 19 {
					hcl[9] = hcl[9] + v.Count
				}
				if v.Hour == 20 || v.Hour == 21 {
					hcl[10] = hcl[10] + v.Count
				}
				if v.Hour == 22 || v.Hour == 23 {
					hcl[11] = hcl[11] + v.Count
				}
			}
		} else {
			hcl = []int{}
		}
		if len(HourCountListYesterday) > 0 {
			for _, v := range HourCountListYesterday {
				if v.Hour == 0 || v.Hour == 1 {
					hcly[0] = hcly[0] + v.Count
				}
				if v.Hour == 2 || v.Hour == 3 {
					hcly[1] = hcly[1] + v.Count
				}
				if v.Hour == 4 || v.Hour == 5 {
					hcly[2] = hcly[2] + v.Count
				}
				if v.Hour == 6 || v.Hour == 7 {
					hcly[3] = hcly[3] + v.Count
				}
				if v.Hour == 8 || v.Hour == 9 {
					hcly[4] = hcly[4] + v.Count
				}
				if v.Hour == 10 || v.Hour == 11 {
					hcly[5] = hcly[5] + v.Count
				}
				if v.Hour == 12 || v.Hour == 13 {
					hcly[6] = hcly[6] + v.Count
				}
				if v.Hour == 14 || v.Hour == 15 {
					hcly[7] = hcly[7] + v.Count
				}
				if v.Hour == 16 || v.Hour == 17 {
					hcly[8] = hcly[8] + v.Count
				}
				if v.Hour == 18 || v.Hour == 19 {
					hcly[9] = hcly[9] + v.Count
				}
				if v.Hour == 20 || v.Hour == 21 {
					hcly[10] = hcly[10] + v.Count
				}
				if v.Hour == 22 || v.Hour == 23 {
					hcly[11] = hcly[11] + v.Count
				}
			}
		} else {
			hcly = []int{}
		}
		return countMattoday, countMatyesterday, hcly, hcl, err
	default:
		return 0, 0, nil, nil, errors.New("countOnl countOff countMat")
	}

}

type HourCount struct {
	Hour  int `json:"hour"`
	Count int `json:"count"`
}

func argMax(arr []HourCount) int {
	maxVal := arr[0].Count
	maxIndex := 0
	for i := 1; i < len(arr); i++ {
		if maxVal < arr[i].Count {
			maxVal = arr[i].Count
			maxIndex = i
		}
	}
	return maxIndex
}

//type OfflineOrderProgress struct {
//	Creator     string    `gorm:"type:varchar(50) json:"creator"`
//	Status      int       `gorm:"type:int(10) json:"status"`
//	OrderId     int       `gorm:"type:int(10) json:"order_id"`
//	OperateTime time.Time `json:"operate_time"`
//}
//
//func (o OfflineOrderProgress) TableName() string {
//	return "offline_order_progress"
//}

func (e *SysOrder) GetBuyRecordByStudentId(studentId int) ([]models.OfflineOrder, []models.OnlineOrder, []models.MaterialOrder) {
	offLineRecords := make([]models.OfflineOrder, 0)
	e.Orm.
		Preload("Customer.Recommenders").Preload("Customer.TeachRecommenders").
		Preload("Course", func(tx *gorm.DB) *gorm.DB {
			return tx.Unscoped()
		}).
		Preload("Department.Department").
		Preload("SubjectRelation").
		Preload("RecheckUser").
		Where("buyer_id = ?", studentId).
		Table(models.OfflineOrder{}.TableName()).Order("id desc").Find(&offLineRecords)

	materialRecords := make([]models.MaterialOrder, 0)
	e.Orm.
		Preload("Customer.Recommenders").Preload("Customer.TeachRecommenders").
		Preload("Material", func(tx *gorm.DB) *gorm.DB {
			return e.Orm.Unscoped()
		}).Preload("SubjectRelation").Preload("DeliverUser").
		Table(models.MaterialOrder{}.TableName()).
		Where("buyer_id = ?", studentId).
		Order("id desc").Find(&materialRecords)

	onlineRecords := make([]models.OnlineOrder, 0)
	e.Orm.Preload("Customer.Recommenders").Preload("Customer.TeachRecommenders").
		Preload("Course", func(tx *gorm.DB) *gorm.DB {
			return tx.Unscoped()
		}).
		Preload("Teacher").Preload("SubjectRelation").
		Table(models.OnlineOrder{}.TableName()).
		Where("buyer_id = ?", studentId).
		Order("id desc").Find(&onlineRecords)
	return offLineRecords, onlineRecords, materialRecords

}
